package com.ymt.fmd.platform.web.rest;

import java.util.Map;
import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;

import com.ymt.fmd.platform.service.MetadataService;
import com.ymt.fmd.util.Const;


/**
 * rest resource for all metadata operations
 * @author fuzheng
 *
 */
@Component
@Path("/metadata")
public class MetadataResource {

	private static Logger logger = Logger.getLogger(MetadataResource.class.getName());
	
	private String resultSucc = "{\"result\":\"success\"}";
	
	private String resultFail = "{\"result\":\"fail\"}";
	
	@Context
	private HttpServletRequest request;
	
	/**
	 * service for metadata operations
	 */
	@Autowired
	private MetadataService mdSrv;
	
	/**
	 * Get enumeration types in i18n table
	 * @return
	 */
	@Path("getEnumerationTypes")
    @GET
    @Produces({ "application/json" })
	public String getEnumerationTypes() {
		Map<String, String> userDetail = (Map<String, String>) SecurityContextHolder.getContext().getAuthentication().getDetails();
		String tenantId = getTenantId(userDetail);
		logger.finer("getEnumerationTypes tenantId="+tenantId);
		String rtn = mdSrv.getEnumerationTypes(tenantId);
		return rtn;
	}
	
	/**
	 * Get enumeration values in i18n table
	 * @param type
	 * @return
	 */
	@Path("getEnumerationValues")
    @GET
    @Produces({ "application/json" })
	public String getEnumerationValues(@QueryParam("type") String type, @QueryParam("target") String target) {
		Map<String, String> userDetail = (Map<String, String>) SecurityContextHolder.getContext().getAuthentication().getDetails();
		String tenantId = getTenantId(userDetail);
		logger.finer("getEnumerationValues tenantId="+tenantId);
		logger.finest("getEnumerationValues type="+type);
		logger.finest("getEnumerationValues target="+target);
		String rtn = mdSrv.getEnumerationValues(tenantId, type, target);
		return rtn;
	}
	
	/**
	 * Get enumerations values in i18n table
	 * @return
	 */
	@Path("getEnumerations")
    @GET
    @Produces({ "application/json" })
	public String getEnumerations(@Context HttpServletRequest request,
			@QueryParam("typeList") String typeList) {
		Map<String, String> userDetail = (Map<String, String>) SecurityContextHolder.getContext().getAuthentication().getDetails();
		String tenantId = getTenantId(userDetail);
		logger.finer("getEnumerations tenantId="+tenantId);
		String lang = userDetail.get(Const.LANG);
		if (lang==null) {
			lang = Const.LANG_ZH;
		}
		logger.finest("getEnumerationValues typeList="+typeList);
		String rtn= mdSrv.getEnumerations(tenantId, lang, typeList);
		logger.finest("getEnumerations rtn:"+rtn);
		return rtn;
	}
	
	/**
	 * Save data in P_I18N
	 * @param values
	 */
	@Path("saveI18N")
    @POST
    @Produces({ "application/json" })
	public String saveI18N(@FormParam("values")String values) {
		try {
			Map<String, String> userDetail = (Map<String, String>) SecurityContextHolder.getContext().getAuthentication().getDetails();
			String tenantId = getTenantId(userDetail);
			logger.finer("saveI18N tenantId="+tenantId);
			logger.finest("saveI18N values="+values);
			mdSrv.saveI18N(tenantId, values);
			//clean affected cache
			cleanAffectedCache();
			return resultSucc;
		} catch (Exception e) {
			e.printStackTrace();
			return resultFail;
		}
	}
	
	/**
	 * Delete data in P_I18N
	 * @param condition
	 */
	@Path("deleteI18N")
    @POST
    @Produces({ "application/json" })
	public String deleteI18N(@FormParam("condition")String condition) {
		try {
			Map<String, String> userDetail = (Map<String, String>) SecurityContextHolder.getContext().getAuthentication().getDetails();
			String tenantId = getTenantId(userDetail);
			logger.finer("deleteI18N tenantId="+tenantId);
			logger.finest("deleteI18N condition="+condition);
			mdSrv.deleteI18N(tenantId, condition);
			//clean affected cache
			cleanAffectedCache();
			return resultSucc;
		} catch (Exception e) {
			e.printStackTrace();
			return resultFail;
		}
	}
	
	/**
	 * Delete data in P_I18N
	 */
	@Path("reorderI18N")
    @POST
    @Produces({ "application/json" })
	public String reorderI18N(
			@FormParam("target")String target, 
			@FormParam("type")String type, 
			@FormParam("orders")String orders) {
		try {
			Map<String, String> userDetail = (Map<String, String>) SecurityContextHolder.getContext().getAuthentication().getDetails();
			String tenantId = getTenantId(userDetail);
			logger.finer("reorderI18N tenantId="+tenantId);
			logger.finest("reorderI18N target="+target);
			logger.finest("reorderI18N type="+type);
			logger.finest("reorderI18N orders="+orders);
			String category = "ENUMERATION";
			mdSrv.reorderI18N(tenantId, category, target, type, orders);
			return resultSucc;
		} catch (Exception e) {
			e.printStackTrace();
			return resultFail;
		}
	}
	
	/**
	 * paging query data in P_I18N
	 */
	@Path("queryDict")
    @POST
    @Produces({ "application/json" })
	public String queryDict(
			@FormParam("args")String args,  
			@FormParam("ordercolumns")String ordercolumns,
			@FormParam("fromRow")int fromRow,
			@FormParam("toRow")int toRow,
			@FormParam("timezoneOffset")int timezoneOffset) {
		try {
			Map<String, String> userDetail = (Map<String, String>) SecurityContextHolder.getContext().getAuthentication().getDetails();
			String tenantId = getTenantId(userDetail);
			logger.finer("queryDict tenantId="+tenantId);
			logger.finest("queryDict args="+args);
			logger.finest("queryDict ordercolumns="+ordercolumns);
			logger.finest("queryDict fromRow="+fromRow);
			logger.finest("queryDict toRow="+toRow);
			logger.finest("queryDict timezoneOffset="+timezoneOffset);
			String lang = userDetail.get(Const.LANG);
			return mdSrv.queryDict(tenantId, args, ordercolumns, lang, fromRow, toRow, timezoneOffset);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * get enumerations for dataproviders
	 * @param dataproviders
	 * @return
	 */
	@Path("getEnumerationsForDp")
    @POST
    @Produces({ "application/json" })
	public String getEnumerationsForDp(
			@FormParam("dataproviders")String dataproviders) {
		try {
			Map<String, String> userDetail = (Map<String, String>) SecurityContextHolder.getContext().getAuthentication().getDetails();
			String tenantId = getTenantId(userDetail);
			logger.finer("getEnumerationsForDp tenantId="+tenantId);
			logger.finest("getEnumerationsForDp dataproviders="+dataproviders);
			String lang = userDetail.get(Const.LANG);
			String rtn = mdSrv.getEnumerationsForDp(tenantId, dataproviders, lang);
			return rtn;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * Get enumeration values in i18n table
	 * @param type
	 * @return
	 */
	@Path("getEnumerationValuesForTreeGrid")
    @GET
    @Produces({ "application/json" })
	public String getEnumerationValuesForTreeGrid(@QueryParam("type") String type, @QueryParam("target") String target) {
		Map<String, String> userDetail = (Map<String, String>) SecurityContextHolder.getContext().getAuthentication().getDetails();
		String tenantId = getTenantId(userDetail);
		logger.finer("getEnumerationValues tenantId="+tenantId);
		logger.finest("getEnumerationValues type="+type);
		logger.finest("getEnumerationValues target="+target);
		try {
			String rtn= mdSrv.getEnumerationValuesForTreeGrid(tenantId, type, target);
			logger.finest("getEnumerationValues rtn:"+rtn);
			return rtn;
		}catch(Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * clean affected caches that will be affected by current operation
	 */
	private void cleanAffectedCache() {
	}
	
	/**
	 * 由于tenantId存在于主键中，所以如果不存在则给一个默认值0
	 * @return
	 */
	private String getTenantId(Map<String, String> userDetail) {
		String tenantId = userDetail.get(Const.TENANT_ID);
		if (tenantId==null) {
			return "0";
		}
		return tenantId;
	}
}
